#pragma once
//负责网络的断开和连接，属于会话层
#include "Socket.hpp"
#include "InetAddr.hpp"
#include <memory>
#include <unistd.h>
#include <signal.h>
#include <functional>

using callback_t = std::function<std::string(std::string&)>;

class TcpServer
{
public:
    TcpServer(uint16_t port, callback_t cb)
        :_port(port)
        ,_listensockfd(std::make_unique<TcpSocket>())
        ,_cb(cb)
    {
        _listensockfd->BuildListenSocketMethod(_port);
    }

    void HandlerRequest(std::shared_ptr<Socket>& sockfd, InetAddr addr)
    {
        std::string inbuffer;//字节流式的队列
        while(true)
        {
            ssize_t n = sockfd->Recv(&inbuffer);
            if(n > 0)
            {
                LOG(Loglevel::DEBUG) << addr.ToString() << "# " << inbuffer;
                std::string send_str = _cb(inbuffer);
                if(send_str.empty())
                    continue;
                sockfd->Send(send_str);
            }
            else if(n == 0)
            {
                LOG(Loglevel::DEBUG) << addr.ToString() << " quit, me too!";
                break;
            }
            else
            {
                LOG(Loglevel::DEBUG) << addr.ToString() << " read error, quit!";
                break;
            }
        }
        sockfd->Close();
    }

    void Run()
    {
        while(true)
        {
            InetAddr client;
            auto sockfd = _listensockfd->Accept(&client);
            if(sockfd == nullptr)
            {
                continue;
            }
            LOG(Loglevel::DEBUG) << "获取一个新连接: " << client.ToString() 
                << ", sockfd : " << sockfd->SockFd();
            if(fork() == 0)
            {
                _listensockfd->Close();//子进程关闭_listensockfd
                HandlerRequest(sockfd, client);
                exit(0);
            }
            sockfd->Close();//父进程关闭sockfd
        }
    }
    ~TcpServer()
    {}

private:
    uint16_t _port;
    std::unique_ptr<Socket> _listensockfd;
    callback_t _cb;
};